//0-1背包
for (int i = 1; i <= n; i++)
  for (int l = W; l >= w[i]; l--) //w为总体积
    f[l] = max(f[l], f[l - w[i]] + v[i]);//转移方程
//完全背包
for (int i = 1; i <= n; i++)
    for (int l = w[i]; l <= W; l++)
      if (f[l - w[i]] + v[i] > f[l]) f[l] = f[l - w[i]] + v[i]; //转移方程

//多重背包
//把每种物品选 k 次等价转换为k个相同的物品，每个物品选一次」。
for (int i = 1; i <= n; i++) {
  for (int weight = W; weight >= w[i]; weight--) {
    // 多遍历一层物品数量
    for (int k = 1; k * w[i] <= weight && k <= cnt[i]; k++) 
    {
      dp[weight] = max(dp[weight], dp[weight - k * w[i]] + k * v[i]);//转移方程
    }
  }
//多重背包（二进制分组优化）用 A{i,j} 代表第 i 种物品拆分出的第 j 个物品。
//具体地说就是令其分别表示由 2^j 个单个物品「捆绑」而成的大物品。
vector<pair<int,int>>goods;
vector<int>f(2010);
void solve()
{
    int n,m;
    cin>>n>>m;
    for(int i = 1;i<=n;i++)
    {
        int v,w,s;
        cin>>v>>w>>s;
        for(int k = 1;k<=s;k*=2)
        {
            s-=k;
            goods.push_back({k*w,k*v});
        }
        if(s>0) goods.push_back({s*w,s*v});
    }
    for(auto &[x,y]:goods)
    {
        for(int j = m;j>=y;j--){
            f[j] = max(f[j],f[j-y]+x);
        }
    }
    cout<<f[m]<<endl;
    return;
}
//二维费用背包，可是不同的是选一个物品会消耗两种价值（经费、时间），
///只需在状态中增加一维存放第二种价值即可。
for (int k = 1; k <= n; k ++ )
{
    for (int i = v; i >= vw[k]; i--)    // 对状态一进行一层枚举
        for (int j = m; j >= mw[k]; j--)  // 对状态二进行一层枚举
            dp[i][j] = max(dp[i][j], dp[i - vw[k]][j - mw[k]] + ww[k]);
}
//分组背包问题，一定不能搞错循环顺序
for (int k = 1; k <= ts; k++)          // 循环每一组
  for (int i = m; i >= 0; i--)         // 循环背包容量
    for (int j = 1; j <= cnt[k]; j++)  // 循环该组的每一个物品
      if (i >= w[t[k][j]])             // 背包容量充足
        dp[i] = max(dp[i],dp[i - w[t[k][j]]] + c[t[k][j]]);  // 像0-1背包一样状态转移

//求方案数初始化总结
//体积至多j,f[i] = 1(0<=i<=m)，用前0种物品，在小于i的空间内，方案数是1，就是什么也不选。
//体积至少j,f[0] = 1，其余为0，在前0种物品中选择，空间至少为0的方案数，只能是什么也不选
//体积恰好j,f[0] = 1，用前i种物品，恰好空间为0的方案，就是什么也不选。


//求最大最小值初始化总结
//体积至多j,f[i] = 0(0<=i<=m)，（只会求价值的最大值）
//体积至少j,f[0] = 0，其余为INF，（只会求价值的最小值）而重量还需要遍历到0，也就是说有体积比需要的体积大的物品还是能用得到
  for(int j = V;j >= 0;j --)
      for(int k = M;k >= 0;k --)
          f[j][k] = min(f[j][k], f[max(0, j - v)][max(0, k - m)] + w);
//体积恰好j：当求价值的最小值：f[0] = 0,其余INF
//体积恰好j：当求价值的最大值：f[0] = 0,其余-INF

//有依赖的背包问题，保证只有一个根,树形背包
int n,m;
int v[110],w[110];
std::vector<int>g[110];
int f[110][110];//f[x][v]表达选择以x为子树的物品，在容量不超过v时所获得的最大价值
void dfs(int x,int m)
{
    for(int i = v[x]; i <= m; i ++) f[x][i] = w[x];//点x必须选，所以初始化f[x][v[x] ~ m]= w[x]
    for(int i = 0; i < g[x].size(); i ++)
    {
        int y = g[x][i];
        dfs(y, m - v[x]);
        for(int j = m; j >= v[x]; j --) //枚举所有要被更新的状态,j的范围为v[x]~m, 小于v[x]无法选择以x为子树的物品
        {
            for(int k = 0; k <= j - v[x]; k ++)  //枚举该子节点在体积j下能使用的所有可能体积数,分给子树y的空间不能大于j-v[x],不然都无法选根物品x
            {
                f[x][j] = max(f[x][j],f[x][j - k] + f[y][k]);
            }
        }
    }
}
void solve()
{
    cin >> n >> m;
    int root = -1;
    for(int i = 1; i <= n; i ++)
    {
        int fa;
        cin >> v[i] >> w[i] >> fa;
        if(fa == -1) root == i;
        else g[fa].push_back(i);
    }
    dfs(root,m);
    cout << f[root][m] << endl;
}   
//多人背包问题
// 他们一共有 K 个人，每个人都会背一个包。这些包的容量是相同的，都是 V。可以装进背包里的一共有 N 种物品，每种物品都
// 有给定的体积和价值。 在 DD 看来，合理的背包安排方案是这样的： 每个人背包里装的物品的总体积恰等于包的容量。 
// 每个包里的每种物品最多只有一件，但两个不同的包中可以存在相同的物品。 任意两个人，他们包里的物品清单不能完全相同。 
// 在满足以上要求的前提下，所有包里的所有物品的总价值最大是多少呢？
int ans,T,n,i,j,k,K,a,b,t,re[45],v[210],w[210],f[5010][45];
int main()
{
    scanf("%d%d%d",&K,&T,&n);
    memset(f,-127,sizeof(f));
    f[0][1]=0;
    for(i=1;i <=n;i ++)scanf("%d%d",&v[i],&w[i]);
    for(i=1;i <= n;i ++)
        for(j=T;j <= v[i];j-- )
        {
            a=b=1,t=0;
            while(t <= K)
                if(f[j][a] >= f[j-v[i]][b]+w[i]) re[++ t]=f[j][a ++];
                else re[++t] = f[j-v[i]][b ++]+w[i];
            for(k=1;k <= K;k ++)f[j][k]=re[k];
        }
    for(i=1;i <= K;i ++)ans+=f[T][i];
    printf("%d",ans);
}